package cc.lucien;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo07 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        Class clazz = Student.class;
        Constructor<Student> constructor = clazz.getDeclaredConstructor(String.class, int.class);
        // 创建对象
        Student student = constructor.newInstance("张三", 30);
        // 获取方法
        Method say = clazz.getDeclaredMethod("say");
        /**
         * 调用方法：
         *  method.invoke(obj, Object...params);
         *  第一个参数表示调用此方法的对象
         *  第二个参数表示调用此方法传递的参数
         *
         *  调用 static 方法可以不传第一个参数
         *  调用无参方法时可以不传第二个参数
         *
         *  如果方法时 private 的，需要先开启访问
         *  method.canAccessible(obj) 返回 obj 对象是否可以访问这个方法
         *  method.setAccess(flag)修改访问
         */
        say.setAccessible(true);
        say.invoke(null);

        /**
         * 操作域（属性）
         * 一般操作摸个对象的域可以通过 getter/setter 方法操作
         * 也可以通过
         *  field.set(obj,value) 设置 obj 对象的 field 属性值为 value
         *  field.get(obj) 获取 obj 对象的 field 属性值
         *  如果要操作 private 的，需要和 method 一样先开启访问
         */

        // 获取 name 属性的相应对象
        Field name = clazz.getDeclaredField("name");
        // 可操作
        name.setAccessible(true);
        // 获取 student 对象的 name 属性值
        Object o = name.get(student);
        System.out.println(o);
        // 设置 student 对象的 name 属性值
        name.set(student,"王五");
        System.out.println(student);
    }
}
